package com.logic.landseaserver.ws;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.logic.landseaserver.models.authcode.bean.UsedAuthCode;
import com.logic.landseaserver.models.authcode.service.CouponUsedService;
import com.logic.landseaserver.ws.request.AddAuthCodeReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.logic.common.enums.HttpCodeEnum;
import com.logic.common.exception.BusinessException;
import com.logic.common.util.CommonResult;
import com.logic.common.util.CommonResultMap;
import com.logic.landseaserver.common.exception.LandseaBusinessException;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.util.LoggerHelper;
import com.logic.landseaserver.domain.PosPaymentCallback;
import com.logic.landseaserver.service.IBillService;
import com.logic.landseaserver.ws.dto.BillSelectAllDTO;
import com.logic.landseaserver.ws.request.CurrentBillReq;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * @Author: jack
 * @Date: 2017/5/24
 * @Description: 账单控制类
 */
@Path("/bill")
@Api(value = "bill")
public class BillRest
{
    
    @Autowired
    private IBillService billServiceImpl;
    
    private static final Logger log = LoggerFactory.getLogger(BillRest.class);

    @Autowired
    private CouponUsedService couponUsedService;
    // 查询当前账单
    @POST
    @Path("/getBillAllForCurrent")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "根据合同id查询当前账单{contractId:xxx}", position = 1)
    public Response getBillAllForCurrent(@ApiParam(value = "param", required = true) Map pmap)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        List<BillSelectAllDTO> billDTOList = null;
        try
        {
            billDTOList = (List<BillSelectAllDTO>)billServiceImpl.getBillByCurrent((HashMap)pmap);
            result.put("projects", billDTOList);
            result.put("total", billDTOList.size());
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("getBillAllForCurrent BusinessException" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 查询当前账单
    @POST
    @Path("/getCurrentBill")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "根据合同id查询当前账单{contractId:xxx}", position = 1)
    public Response getCurrentBill(@ApiParam(value = "param", required = true) CurrentBillReq req)
    {
        CommonResultMap map = new CommonResultMap();
        try
        {
            map.setData(billServiceImpl.getBillInfoByCurrent(req));
            map.setResult(CommonResult.SUCCESS, "createFirstBill success");
        }
        catch (BusinessException e)
        {
            log.info("createFirstBill BusinessException" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        catch (Exception e)
        {
            log.info("createFirstBill Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    @POST
    @Path("/user/getBillList")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "个人中：账单列表", position = 1)
    public Response getNopayBill(@ApiParam(value = "param", required = true) CurrentBillReq req)
    {
        CommonResultMap map = new CommonResultMap();
        try
        {
            map.setData(billServiceImpl.getBillList(req));
            map.setResult(CommonResult.SUCCESS, "getBillList success");
        }
        catch (BusinessException e)
        {
            log.info("getBillList BusinessException" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        catch (Exception e)
        {
            log.info("getBillList Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    @GET
    @Path("/user/getBillDetail/{billId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "账单详情", position = 1)
    public Response getBillDetail(@ApiParam(value = "param", required = true) @PathParam("billId") Integer billId)
    {
        CommonResultMap map = new CommonResultMap();
        try
        {
            map.setData(billServiceImpl.getBillDetail(billId));
            map.setResult(CommonResult.SUCCESS, "getBillDetail success");
        }
        catch (Exception e)
        {
            log.info("getBillDetail Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 查询当前账单
    @POST
    @Path("/admin/getBillList")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "查询合同账单列表", position = 1)
    public Response getBillList(@ApiParam(value = "param", required = true) CurrentBillReq req)
    {
        CommonResultMap map = new CommonResultMap();
        try
        {
            map.setData(billServiceImpl.queryBillList(req));
            map.setResult(CommonResult.SUCCESS, "getBillList success");
        }
        catch (BusinessException e)
        {
            log.info("getBillList BusinessException" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        catch (Exception e)
        {
            log.info("getBillList Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    @GET
    @Path("/admin/getBill/{billId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "根据账单编号查询账单详情", position = 1)
    public Response getBillsForId(@PathParam("billId") Integer billId)
    {
        CommonResultMap map = new CommonResultMap();
        try
        {
            map.setData(billServiceImpl.queryBillDetailAndPayList(billId));
            map.setResult(CommonResult.SUCCESS, "getBillsForId success");
        }
        catch (LandseaBusinessException e)
        {
            log.info("getBillsForId BusinessException" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        catch (Exception e)
        {
            log.info("getBillsForId Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    @POST
    @Path("/createFirstBill/{contractId}")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "createFirstBill by contractId", position = 2)
    public Response createFirstBill(
        @ApiParam(value = "param", required = true) @PathParam("contractId") Integer contractId)
    {
        CommonResultMap map = new CommonResultMap();
        try
        {
            HashMap queryMap = new HashMap();
            queryMap.put("mainType","CONTRACT");
            queryMap.put("mainId",contractId);
            //获取当前合同的授权码
            List<UsedAuthCode> authCodes = couponUsedService.queryCouponUesd(queryMap);
            billServiceImpl.createFirstBill(contractId,authCodes);
            map.setData(null);
            map.setResult(CommonResult.SUCCESS, "createFirstBill success");
        }
        catch (LandseaException e)
        {
            LoggerHelper.handleException(log, "createFirstBill", e, map);
        }
        catch (Exception e)
        {
            log.info("createFirstBill Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 部分支付返回true，未支付返回false
    @POST
    @Path("/getBillStatusForId")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "给合同编辑调用，根据合同id查询支付状态：部分支付返回true，未支付返回false，全部支付返回：true。", position = 3)
    public Response getBillStatusForId(
        @ApiParam(value = "param", required = true) @QueryParam("contractId") Integer contractId)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        boolean isBillStatus;
        try
        {
            isBillStatus = billServiceImpl.getBillStatusForId(contractId);
            result.put("isBillStatus", isBillStatus);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("getBillStatusForId Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 部分支付返回true，未支付返回false
    @POST
    @Path("/getBillStatusForPayment")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "给微众收银台调用，支付成功查询支付状态：部分支付返回false，未支付返回false，全部支付返回：true。", position = 4)
    public Response getBillStatusForPayment(
        @ApiParam(value = "param", required = true) @QueryParam("contractId") Integer contractId)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        boolean isBillStatus;
        try
        {
            isBillStatus = billServiceImpl.getBillStatusForContractId(contractId);
            result.put("isBillStatus", isBillStatus);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("getBillStatusForPayment Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 支付成功后修改账单状态
    @POST
    @Path("/changeBillStatus")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "支付成功后修改账单状态", position = 5)
    public Response changeBillStatus(@ApiParam(value = "param", required = true) @QueryParam("billId") Integer billId)
    {
        log.info("BillRest|changeBillStatus|Request|billId" + billId);
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            billServiceImpl.changeBillStatus(billId, 0.00d);
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("changeBillStatus Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 支付成功后生成正式合同编号，合同状态，账单状态，支付状态
    @POST
    @Path("/getConBillStatus")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "POS端支付成功回调修改账单状态，支付状态{contractId:xxx,billId:xxx}", position = 6)
    public Response getConBillStatus(@ApiParam(value = "param", required = true) PosPaymentCallback posPaymentCallback)
    {
        log.info("BillRest|getConBillStatus|Request|" + posPaymentCallback.toString());
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            billServiceImpl.posPayCallBackHandle(posPaymentCallback);
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (LandseaException e)
        {
            LoggerHelper.handleException(log, "getConBillStatus", e, map);
        }
        catch (Exception e)
        {
            log.info("getConBillStatus Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
    
    // 微众支付成功后生成正式合同编号，合同状态，账单状态。
    @POST
    @Path("/createMonthBill")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "测试生成月账单", position = 8)
    public Response createMonthBill()
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            billServiceImpl.createMonthBill();
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("createMonthBill Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }


    // 微众支付成功后生成正式合同编号，合同状态，账单状态。
    @POST
    @Path("/createLateFee")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "产生滞纳金", position = 8)
    public Response createLateFee()
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            billServiceImpl.createLateFee();
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("createMonthBill Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }

    @POST
    @Path("/testSendMsgForOffBill")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "测试退房账单未处理，群发短信通知管家")
    public Response testSendMsgForOffBill() {
        CommonResultMap map = new CommonResultMap();
        try {
            billServiceImpl.delayOffBillSendMsg();
            map.setResult(CommonResult.SUCCESS);
        } catch (LandseaException e) {
            log.error("offRent || testSendMsgForOffBill error.", e);
            map.setResult(CommonResult.ERROR, e.getErrorDesc());
        } catch (Exception e) {
            log.error("offRent || testSendMsgForOffBill error.", e);
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }

    @POST
    @Path("/createMonthBill/{contractId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "测试生成月账单", position = 8)
    public Response createMonthBillByContractId( @ApiParam(value = "param", required = true) @PathParam("contractId") Integer contractId)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            billServiceImpl.createMonthBillByContractId(contractId);
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("createMonthBill Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }


    @POST
    @Path("/testSendMonthBillMsg")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "测试月账单发送短信以及推送消息", position = 8)
    public Response testSendMonthBillMsg(@ApiParam(value = "param", required = true)HashMap pmap)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            log.info("Task for testSendMonthBillMsg start");
            /*HashMap msgMap = new HashMap();
            msgMap.put("sendDate", DateUtil.getInstence().convertDate(new Date()));
            msgMap.put("billName", "第"); //月结账单
            msgMap.put("billStatus", BillStatusEnum.BIST3.getCode());
             msgMap.put("contractId", "xx")*/
            billServiceImpl.sendMsgByMonthBill(pmap);
            log.info("Task for sendMonthBillMsg end");
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("createMonthBill Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }

    @POST
    @Path("/addAuthCode")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "保存优惠劵使用记录->月结账单")
    public Response usedAuthCode(
            @ApiParam(value = "param", required = true) AddAuthCodeReq req) {
        CommonResultMap map = new CommonResultMap();
        try {
            billServiceImpl.addAuthCode(req);
            map.setResult(CommonResult.SUCCESS);
        }catch (LandseaException e) {
            log.error("MonthBill || addAuthCode error.", e);
            map.setResult(CommonResult.ERROR, e.getErrorDesc());
        } catch (Exception e) {
            log.error("MonthBill || addAuthCode error.", e);
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }


    @POST
    @Path("/checkBillPay/{contractId}")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "校验是否存在未支付的账单", position = 8)
    public Response checkBillPay(@ApiParam(value = "param", required = true) @PathParam("contractId") Integer contractId)
    {
        CommonResultMap map = new CommonResultMap();
        try{
            HashMap resultMap  = new HashMap();
            resultMap.put("result", billServiceImpl.checkBillPay(contractId));
            map.setData(resultMap);
            map.setResult(CommonResult.SUCCESS, "checkBillPay success");
        }catch (LandseaException e){
            LoggerHelper.handleException(log, "checkBillPay", e, map);
        } catch (Exception e){
            log.info("checkBillPay Exception" + e.getMessage());
            map.setResult(CommonResult.ERROR, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }


    @POST
    @Path("/createMonthBillByIds")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "测试生成月账单-ids", position = 8)
    public Response createMonthBillByIds(@ApiParam(value = "param", required = true) @QueryParam("ids") String ids)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try
        {
            billServiceImpl.createMonthBillByCIds(ids);
            result.put("STATUS", 0);
            map.setData(result);
        }
        catch (Exception e)
        {
            log.info("createMonthBill Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }

    @POST
    @Path("/changeBill/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "拆分月结账单", position = 9)
    public Response changeBill(@ApiParam(value = "param", required = true) @PathParam("id") Integer id)
    {
        CommonResultMap map = new CommonResultMap();
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            billServiceImpl.changeBill(id);
            result.put("STATUS", 0);
            map.setData(result);
        }catch (LandseaException e) {
            log.error("billRest || changeBill error.", e);
            map.setResult(CommonResult.ERROR, e.getErrorDesc());
        }catch (Exception e){
            log.info("changeBill Exception" + e.getMessage());
            map.setResult(CommonResult.BUSINESS_EXCEPTION, e.getMessage());
        }
        return Response.status(HttpCodeEnum.OK.getCode()).entity(map).build();
    }
}
